﻿namespace LogManager.Utils.ChangeTracking
{
    using NUnit.Framework;
    using System;
    using System.Collections.Generic;

    public class TestDependPropertyChangeBase
    {
        [Test]
        public void DependPropertyChangeBase_Ctor_InexistentPropertyDependency_ArgumentExceptionThrown()
        {
            Assert.Throws<ArgumentException>(() => new TestBadClass());
        }

        [Test]
        public void DependPropertyChangeBase_RaisePropertyChanged_NoReferences_OnlyRaisedForProperty()
        {
            var testInst = new TestClass();
            var results = new List<string>();

            testInst.PropertyChanged += (sender, args) =>
            {
                results.Add(args.PropertyName);
                Assert.AreEqual(sender, testInst);
            };

            testInst.RaisePropertyChanged("Pseudo");

            Assert.IsTrue(results.Count == 1);
            Assert.IsTrue(results.Contains("Pseudo"));
        }

        [Test]
        public void DependPropertyChangeBase_RaisePropertyChanged_OneTimeReferenced_DependenciesCalled()
        {
            var testInst = new TestClass();
            var results = new List<string>();

            testInst.PropertyChanged += (sender, args) =>
            {
                results.Add(args.PropertyName);
                Assert.AreEqual(sender, testInst);
            };

            testInst.RaisePropertyChanged("LastName");

            Assert.IsTrue(results.Count == 2);
            Assert.IsTrue(results.Contains("LastName"));
            Assert.IsTrue(results.Contains("FullName"));
        }

        [Test]
        public void DependPropertyChangeBase_RaisePropertyChanged_MultipleReferences_DependenciesCalled()
        {
            var testInst = new TestClass();
            var results = new List<string>();

            testInst.PropertyChanged += (sender, args) =>
            {
                results.Add(args.PropertyName);
                Assert.AreEqual(sender, testInst);
            };

            testInst.RaisePropertyChanged("FirstName");

            Assert.IsTrue(results.Count == 3);
            Assert.IsTrue(results.Contains("FirstName"));
            Assert.IsTrue(results.Contains("FullName"));
            Assert.IsTrue(results.Contains("Pseudo"));
        }

        public class TestClass : DependPropertyChangeBase
        {
            public string FirstName { get; set; }
            public string LastName { get; set; }

            [DependsUpon("FirstName")]
            [DependsUpon("LastName")]
            public string FullName
            {
                get
                {
                    return FirstName + " " + LastName;
                }
            }

            [DependsUpon("FirstName")]
            public string Pseudo
            {
                get
                {
                    return FirstName + "99";
                }
            }
        }

        public class TestBadClass : DependPropertyChangeBase
        {
            public string LastName { get; set; }

            [DependsUpon("BadName")]
            public string FullName
            {
                get
                {
                    return "";
                }
            }
        }
    }
}
